﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Core;
using System.Numerics;
using Microsoft.Win32;
using System.IO;

namespace Desktop
{
    /// <summary>
    /// Interaction logic for DigitalSignature.xaml
    /// </summary>
    public partial class DigitalSignature : UserControl
    {
        public DigitalSignature()
        {
            InitializeComponent();
            editorDS.TextType = Editor.Editor.HEX_TYPE;
            keyPublic.FileFilter = "pub files|*.pub";
            keyValue.FileFilter = "n files|*.n";
        }

        private void CheckBoxAddToEOF_Checked(object sender, RoutedEventArgs e)
        {
            //editorDS.IsEnabled = false;
        }

        private void CheckBoxAddToEOF_Unchecked(object sender, RoutedEventArgs e)
        {
            //editorDS.IsEnabled = true;
        }

        private void ButtonGenerate_Click(object sender, RoutedEventArgs e)
        {
            if (IsFormValid())
            {
                // Hash
                String hash = SHA.doSHA1(Converter.ToBytes(editorMessage.GetText()));
                Console.WriteLine(hash);

                // Encrypt
                BigInteger publicKey = BigInteger.Parse(keyPublic.Text);
                BigInteger nValue = BigInteger.Parse(keyValue.Text);
                BigInteger[] bigInts = RSA.EncryptFinalRSA(hash, publicKey, nValue);

                // Add to View
                editorDS.SetText(Converter.ToString(bigInts));

                if (checkBoxAddToEOF.IsChecked == true)
                {
                    AddDSToEOF();
                }
            }
        }

        private void AddDSToEOF()
        {
            // Open save dialog
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.RestoreDirectory = true;
            String fileName = null;

            // Show save file dialog
            if (sfd.ShowDialog() == true)
            {
                fileName = sfd.FileName;

                if (fileName != null)
                {
                    // Save file
                    saveFile(fileName);
                }
            }
        }

        private void saveFile(string fileName)
        {
            // Get message
            string msg = editorMessage.GetText();
            byte[] msgBytes = Converter.ToBytes(msg);

            // Get DS
            string ds = editorDS.GetText();
            byte[] dsBytes = Converter.ToBytes(ds);
            
            // Create file
            FileStream fs = new FileStream(fileName, FileMode.Create);

            // Add message
            fs.Write(msgBytes, 0, msgBytes.Length);

            // Add null character
            fs.WriteByte(0);

            // Add DS
            fs.Write(dsBytes, 0, dsBytes.Length);

            // Close
            fs.Close();
        }

        

        private bool IsFormValid()
        {
            if (editorMessage.GetText().Length < 1)
            {
                Helper.ShowError("Message must be filled");
                return false;
            }

            if (keyPublic.Text.Length < 1)
            {
                Helper.ShowError("Key must be filled");
                return false;
            }

            if (!isValidNumber(keyPublic.Text, "Key"))
            {
                return false;
            }

            if (keyValue.Text.Length < 1)
            {
                Helper.ShowError("Value of N must be filled");
                return false;
            }

            if (!isValidNumber(keyValue.Text, "Value of N"))
            {
                return false;
            }

            return true;
        }

        private bool isValidNumber(string number, string variabel)
        {
            if (!Helper.isNumber(number))
            {
                Helper.ShowError(variabel + " is not a number.");
                return false;
            }

            BigInteger bigInt = BigInteger.Parse(number);
            BigInteger temp = 1;
            if (bigInt < (temp << 31))
            {
                Helper.ShowError(variabel + " minimal 32 bit");
                return false;
            }

            return true;
        }
    }
}
